#ifndef REFUELLING_H
#define REFUELLING_H

#include "refuelling_struct_csv.hpp"
#include "file_list.hpp"

class refuelling
{
  public:
	inline refuelling() { }

	inline virtual ~refuelling () {};

	// total amount of money spent for fuel in the period
	//virtual float total_amount(int _plate_id, date _first_date, date _last_date, bool _include_last_date = true) =0;

	// total liters of fuel consumed in the period
	//virtual float total_fuel(int _plate_id, date& _first_date, date& _last_date, bool _include_last_date = true) =0;

	// mean fuel consumption expressed in liter/km
	//virtual float mean_fuel_consumption(int _plate_id, date _first_date, date _last_date, bool _include_last_date = true) = 0;

	// estimate of fuel consumption in a specified date
	//virtual float estimated_fuel_consumption(int _plate_id, date _date, bool _include_last_date = true) = 0;

	// mean fuel distance expressed in km/liter
	//virtual float mean_fuel_distance(int _plate_id, date _first_date, date _last_date, bool _include_last_date = true) = 0;

	// find latest fuel price
	//virtual float latest_price(int _plate_id, date _date) = 0;
	
  private:
};



// implementation for csv files

class refuelling_csv: public refuelling
{
  public:

	inline refuelling_csv(char* filename): file(filename) { }

	inline refuelling_csv(): file(file_list::refuelling_filename()){}

	static float latest_price(int _plate_id, boost::gregorian::date _date);
	
	static float total_amount(int _plate_id, boost::gregorian::date _first_date, boost::gregorian::date _last_date, bool _include_last_date = true);
	
	static float total_fuel(int _plate_id, boost::gregorian::date& _first_date, boost::gregorian::date& _last_date, bool _include_last_date = true);
	
	static float mean_fuel_consumption(int _plate_id, boost::gregorian::date _first_date, boost::gregorian::date _last_date, bool _include_last_date = true);
	
	static float estimated_fuel_consumption(int _plate_id, boost::gregorian::date _date, bool _include_last_date = true);
	
	static float mean_fuel_distance(int _plate_id, boost::gregorian::date _first_date, boost::gregorian::date _last_date, bool _include_last_date = true);
		

private:
	
	static const enum period_tags
	{	
		LAST_BEFORE_PERIOD_PRE = 0,
		LAST_BEFORE_PERIOD,
		FIRST_IN_PERIOD,
		LAST_IN_PERIOD,	
		FIRST_AFTER_PERIOD,
		FIRST_AFTER_PERIOD_POST
	} period_field;


	static bool check_outside(boost::gregorian::date& _first_date, boost::gregorian::date& _last_date, refuelling_struct_csv& row, boost::gregorian::date* _reference_date, float* _reference_km);
	
	static bool check_inside(boost::gregorian::date& _first_date, boost::gregorian::date& _last_date, refuelling_struct_csv& row, boost::gregorian::date* _reference_date, float* _reference_km, bool& _not_yet_in_period);


	// This method modifies time intervals to include only lines with information about kilometers.
	// Particularly, in order to take into account the last date in the period, the first valid date after that time interval has to be included.
	// On the other hand, if its last date has not to be considered, the last valid date before that period is included.

	static float check_km_and_period(int _plate_id, boost::gregorian::date& _first_date, boost::gregorian::date& _last_date, bool _include_last_date = true);

	static float find_km_in_period(boost::gregorian::date& _first_date, boost::gregorian::date& _last_date, boost::gregorian::date* _period_ref_date, float* _period_ref_km, bool _include_last_date = true);
	
  protected:
	static bool check_parm(refuelling_struct_csv& row, 
		int _plate_id, boost::gregorian::date _first_date, boost::gregorian::date _last_date, bool _include_last_date = true);		


  private:
	static bool check_parm(refuelling_struct_csv& row, int _plate_id, boost::gregorian::date _date);

	std::string file;
};
#endif
